﻿module Sustainalytics.Portfolio {

    import Common = Sustainalytics.Common;

    export class PortfolioService implements IPortfolioService {

        private staticObjects: Common.IStaticObjects;
        private urlBase: string;

        // Ctor.
        constructor(
            private $q: ng.IQService,
            private $http: ng.IHttpService,
            private notificationFactory: Common.INotificationFactory,
            staticObjects: Common.IStaticObjects,
            private ClaimsAuthorizationService: Sustainalytics.Claims.ClaimsAuthorizationService) {

            this.staticObjects = staticObjects;
            this.urlBase = staticObjects.portfolioBaseUrl;
        }

        public hasPermision(): boolean {
            var ctx = this;

            var params: Sustainalytics.Claims.ResourceParameters[] = new Array();

            var paramOverallAssessment = new Sustainalytics.Claims.ResourceParameters();
            paramOverallAssessment.key = 'shortName';
            paramOverallAssessment.value = 'portfoliomanagement';
            params.push(paramOverallAssessment);

            var valid = ctx.ClaimsAuthorizationService.Validate('api/v1/portfolios', 'GET', params);
            return valid;
        }

        // show error message for a given error code
        private showError(err) {
            var ctx = this;
            if (err && err['errorCode'])
                ctx.notificationFactory.error('', ctx.staticObjects.getErrorMesageByStatusCode(err['errorCode'],  err['errorCode']));
        }

        private showMessage(msg) {
            var ctx = this;
            ctx.notificationFactory.success(msg);
        }

        // get paged list of portfolio
        public getPortfolios(filter: PortfolioFilterDto, skip: number, take: number, orderBy: string[], orderByAsc: boolean, accountId: string, userId: string) {
            var ctx = this;
            var def = this.$q.defer();

            var options = new Common.ListOptions();
            options.skip = skip;
            options.take = take;
            options.orderBy = orderBy;
            options.orderAscending = orderByAsc;
            options.includeAllFields = true;
            options.getCount = true;

            var params = $.param({
                isMyPortfolio: filter.isMyPortfolio,
                namePortfolio: filter.namePortfolio,
                sharingStatus: filter.sharingStatus,
                portfolioType: filter.portfolioType,
                isNameEqual: filter.isNameEqual,
                accountId: accountId,
                userId: userId,
                listOptions: options
            });

            var url = this.urlBase + "/api/v1/portfolios?" + params;
            var promise = this.$http.get(url);

            promise.success(
                function(data) {
                    def.resolve(data);
                }).error(
                function(err) {
                    ctx.showError(err);
                    def.reject();
                });

            return def.promise;
        }

        //get count of portfolios
        public getPortfolioCount(filter: PortfolioFilterDto, accountId: string, userId: string) : ng.IPromise<PortfolioListDto>
        {
            var def = this.$q.defer();

            var options = new Common.ListOptions();
            options.skip = 0;
            options.take = 1;
            options.orderBy = null;
            options.orderAscending = null;
            options.includeAllFields = false;
            options.getCount = true;

            var params = $.param({
                isMyPortfolio: filter.isMyPortfolio,
                namePortfolio: filter.namePortfolio,
                sharingStatus: filter.sharingStatus,
                portfolioType: filter.portfolioType,
                isNameEqual: filter.isNameEqual,
                accountId: accountId,
                userId: userId,
                listOptions: options
            });

            var url = this.urlBase + "/api/v1/portfolios?" + params;
            var promise = this.$http.get(url);

            promise.success(
                data => {
                    def.resolve(data);
                }).error(
                err => {
                    this.showError(err);
                    def.reject();
                });

            return def.promise;
        }

        //addPortfolio
        public addPortfolios(portfolioAdd: PortfolioAddDto) {

            var ctx = this;
            var def = this.$q.defer();
            
            var url: string = '/screeningtoolserv/api/v1/portfolios';
            //var url: string = this.urlBase + '/api/v1/portfolios';

            var promise: ng.IHttpPromise<{}> = this.$http.post(url, portfolioAdd);

            promise.success(function (data) {

                ctx.showMessage("Portfolio saved successfully!");
                if (data && data["warningCode"]) {
                    ctx.notificationFactory.warn(ctx.staticObjects.getMessageByInternalCode(data["warningCode"]));
                    ctx.showMessage("Portfolio saved successfully!");
                } else {
                    ctx.showMessage("Portfolio saved successfully!");
                }

                def.resolve(data);
                })
                .error(function(err) {
                    ctx.showError(err);
                    def.reject();
                });

            return def.promise;
            
        }

        //updatePortfolio
        public updatePortfolios(portfolioUpdate: PortfolioAddDto) {

            var ctx = this;
            var def = this.$q.defer();

            var url: string = '/screeningtoolserv/api/v1/portfolios';
            //var url: string = this.urlBase + '/api/v1/portfolios';

            var promise: ng.IHttpPromise<{}> = this.$http.put(url, portfolioUpdate);

            promise.success(function(data) {
                
                if (data && data["warningCode"]) {
                    ctx.notificationFactory.warn(ctx.staticObjects.getMessageByInternalCode(data["warningCode"]));
                    ctx.showMessage("Portfolio saved successfully!");
                } else {
                    ctx.showMessage("Portfolio saved successfully!");
                }
                    def.resolve(data);
                })
                .error(function(err) {
                    ctx.showError(err);
                    def.reject();
                });

             return def.promise;
        }

        //deletePortfolio
        public deletePortfolio(id: string) {
            var ctx = this;
            var def = this.$q.defer();

            var url: string = this.urlBase + '/api/v1/portfolios/' + id;

            var promise: ng.IHttpPromise<{}> = this.$http['delete'](url);

            promise.success(function(data) {
                    //ctx.showMessage("Portfolio deleted successfully!");
                    def.resolve(data);
                })
                .error(function(err) {
                    ctx.showError(err);
                    def.reject();
                });
            return def.promise;
        }

        public updateStatusPortfolio(portfolioSharing: PortfolioSharingDto) {
            var def = this.$q.defer();
            var url: string = this.urlBase + '/api/v1/portfolios/';
            var httpConfig: ng.IRequestConfig = { method: 'PATCH', url: url, data: portfolioSharing };
            var promise = this.$http(httpConfig);
            promise.success(data => { def.resolve(data); }).error(err => {
                this.showError(err);
                def.reject();
            });
            return def.promise;
        }

        public updatePortfolioDetailWeight(portfolioId: string, portfolioDetailId: string, newValue: number, isEmptyValue: boolean) {
            var ctx = this;
            var def = this.$q.defer();
            var url: string = this.urlBase + '/api/v1/portfolios?portfolioId=' + portfolioId + '&portfolioDetailId=' + portfolioDetailId + '&newWeightValue=' + newValue + '&isEmptyValue=' + isEmptyValue;
            var httpConfig: ng.IRequestConfig = { method: 'PATCH', url: url };
            var promise = this.$http(httpConfig);
            promise
                .success(function (data) {
                    def.resolve(data);
                })
                .error(function (err) {
                    ctx.showError(err);
                    def.reject();
                });
            return def.promise;
        }


        public renamePortfolio(portfolioRename: PortfolioRenameDto) {
            var ctx = this;
            var def = this.$q.defer();
            var url: string = this.urlBase + '/api/v1/portfolios' + '?id=' + portfolioRename.id + '&newName=' + portfolioRename.newPortfolioName;
            var httpConfig: ng.IRequestConfig = { method: 'PATCH', url: url };
            var promise = this.$http(httpConfig);
            promise
                .success(function(data) {
                    def.resolve(data);
                })
                .error(function(err) {
                    ctx.showError(err);
                    def.reject();
                });
            return def.promise;
        }

        public updateSecurityWeight(portfolioMatchid: string, newValue: number, isUnmatched: boolean) {
            var ctx = this;
            var def = this.$q.defer();
            var url: string = this.urlBase + '/api/v1/portfolios?portfolioMatchId=' + portfolioMatchid + '&newWeightValue=' + newValue + '&isUnmatched=' + isUnmatched;
            var httpConfig: ng.IRequestConfig = { method: 'PATCH', url: url};
            var promise = this.$http(httpConfig);
            promise
                .success(function (data) {
                    def.resolve(data);
                })
                .error(function (err) {
                    ctx.showError(err);
                    def.reject();
                });
            return def.promise;
        }

        public getPortfolioById(portfolioId: string, accountId: string, userId: string): ng.IPromise<PortfolioDto> {
            var ctx = this;
            var def = this.$q.defer();
            
            var query =
                {
                    accountId: accountId,
                    userId: userId,
                };

            var url = this.urlBase + '/api/v1/portfolios/' + portfolioId + "?" + $.param(query);
            var promise = this.$http.get(url);
            promise
                .success(function (data)
                {
                    def.resolve(data);
                    //if (userId == data["addedByUserId"]) {
                    //    data["isMyPortfolio"] = true;
                    //}
                    //else {
                    //    data["isMyPortfolio"] = false;
                    //}
                })
                .error(function (err)
                {
                    ctx.showError(err); def.reject();
                })
            return def.promise;
        }

        public Generate(selectedFromMyPortfolios: string, selectedFromAllPortfolios: string) {
            var ctx = this;
            var def = this.$q.defer();

            var params = $.param({
                portf1: selectedFromMyPortfolios[0]["id"],
                portf2: selectedFromAllPortfolios[0]["id"]
            });

            var url = ctx.urlBase + "/api/v1/portfolios?" + params;

            var promise = this.$http.get(url);

            promise.success(
                data => {
                    def.resolve(data);
                }).error(
                err => {
                    this.showError(err);
                    def.reject();
                });

            return def.promise;

        }

        public getMyPortfolios(userId: string, accountId: string, getAll: boolean, getOnlyAutomaticSystemPorfolios?: boolean): ng.IPromise<{}> {
            var def = this.$q.defer();

            var params = $.param({
                userId: userId,
                accountId: accountId,
                getAllPortfolios: getAll,
                onlyAutomaticSystemPortfolios: getOnlyAutomaticSystemPorfolios
            });

            var url: string = this.urlBase + '/api/v1/subscribetoportfolio?' + params;
            var promise = this.$http.get(url); //(httpConfig);

            promise.success(
                data => {
                    def.resolve(data);
                }).error(
                err => {
                    this.showError(err);
                    def.reject();
                });

            return def.promise;
        }
    }


    // register service with Portfolio Angular module
    angular.module(portfolioModuleName).service('PortfolioService',
        ['$q', '$http', 'notificationFactory', 'staticObjects', 'ClaimsAuthorizationService', PortfolioService]);
} 